home *** CD-ROM | disk | FTP | other *** search
- #ifndef WFileIncluded
- #define WFileIncluded
-
- // copyright (c) 1992, 1993 by Paul Wheaton
- // 1916 Brooks #205, Missoula, MT 59801
- //
- // phone: (406)543-1928
- // CompuServe: 72707,207
- // Internet: 72707.207@CompuServe.com
-
- /*
-
- Although these routines lean on ANSI stdio functions, many of them work
- somewhat differently. "File" is for binary mode and "TextFile" is for
- text mode. The constructor will open the file (create it if it doesn't
- exist). It is the applications programmers responsibility to make sure
- that the filename given is valid and possible. If the file cannot be
- opened, the program will be stopped.
-
- Binary files:
-
- Reading and writing may be done to any byte location that will fit into a
- long. Writing more than a byte beyond the EOF will simply generate garbage
- characters from the EOF up to the point you are now writing. Reading
- beyond EOF will result in a garbage read and the Read function will return
- False.
-
- Text files:
-
- After opening, the first read will be done from the beginning of the file
- and the first write will be done to the end of the file.
-
- Note!: if a special buffer size has been requested and *denied* (due to
- lack of heap space), a beep will sound but file access will continue
- with the default buffer size.
-
- */
-
- #include <stdio.h>
- #include <io.h>
- #include <WMisc.h>
- #include <WVec.h>
-
- #ifdef MAJORBBS
-
- Bool FileExists(const char*);
-
- #else
-
- #define FileExists(FileName) (!access(FileName,0))
- // returns True if the file exists
-
- #endif
-
-
- char CurDiskDrive();
-
- long DiskSpace(const char Drive='.'); // '.' means default drive
- // the value returned is in "K" or "kilobytes" or number of 1024 byte blocks
- // this is in case this library is on a computer that can handle capacity
- // of more than 2 gigs that a "long" could represent.
-
- long FileSize(const char* FileName);
- // the value returned is in bytes
-
- #define WriteThing(A) Write(&A,sizeof(A))
- #define ReadThing(A) Read(&A,sizeof(A))
- // use only on things where the size can be properly determined with
- // "sizeof". Use only with "File" not "TextFile"
-
- void DeleteFile(const char* FileName);
- // if the file is deletable, it's deleted
-
- const ReadAndWrite=0;
- const ReadOnly=1;
-
- class LowLevelFile
- {
- FILE* FilePointer;
- Bool Open;
- char* GivenFileName;
- char* Buf; // for future use to change the size of the buffer
- void InternalInit(int);
- friend class File;
- friend class TextFile;
- friend class RecFileRef;
- friend class RecFile;
- public:
- LowLevelFile(const char* FileName,const char* Mode, int BufSize);
- //LowLevelFile(const char* FileName,int Share,const char* Mode, int BufSize);
- ~LowLevelFile() {Close();}
- void Close(); // you can close the file early if you want
- void Flush() {fflush(FilePointer);}
- // flush your write buffers out to disk
- long CurPos() {return ftell(FilePointer);}
- // current file position: where you are about to write to or read from
- void Seek(long Offset) {fseek(FilePointer,Offset,0);}
- void SeekBOF(){fseek(FilePointer,0,0);}
- void SeekEOF(){fseek(FilePointer,0,2);}
- long Size(); // the file size in bytes
- Bool EndOfFile() {return feof(FilePointer);}
- #ifdef MAJORBBS
- void* operator new(size_t size){return malloc(size);}
- void operator delete(void* p) {free(p);}
- #endif
- };
-
- class File:public LowLevelFile
- {
- public:
- File(const char* FileName,Bool Mode=ReadAndWrite,int BufSize=BUFSIZ);
- Bool Read(void *Buffer,int Size=1);
- Bool Read(ByteVector& BV,int Size=1);
- void Write(const void *Buffer,int Size=1);
- };
-
- class RecFile:public LowLevelFile
- {
- int RecSize;
- public:
- RecFile(const char* FileName,int RecordSize,Bool Mode,int BufSize);
- Bool Read(void *Buffer);
- Bool Read(void *Buffer,int Quan);
- void Seek(long RecNum);
- long CurRec(); // record number
- long Size(); // number of recs
- void Write(const void *Buffer);
- void Write(const void *Buffer,int Quan);
- };
-
- #define CreateRecFileClass(ClassName,StructType) \
- \
- class ClassName; \
- \
- class ClassName ## Ref \
- { \
- ClassName* F; \
- ClassName ## Ref(ClassName* XF){F=XF;} \
- friend class ClassName; \
- public: \
- void operator=(const StructType& X); \
- operator StructType(); \
- void* operator new(size_t size){return malloc(size);} \
- void operator delete(void* p) {free(p);} \
- }; \
- \
- class ClassName:public RecFile \
- { \
- public: \
- ClassName(const char* FileName,Bool Mode=ReadAndWrite, \
- int BufSize=BUFSIZ): \
- RecFile(FileName,sizeof(StructType),Mode,BufSize){} \
- Bool Read(StructType& X){return RecFile::Read(&X);} \
- Bool Read(StructType* X,int Q){return RecFile::Read(X,Q);} \
- void Write(const StructType& X){RecFile::Write(&X);} \
- void Write(const StructType* X,int Q){RecFile::Write(X,Q);} \
- ClassName ## Ref operator[](long RecNum) \
- {Seek(RecNum); return ClassName ## Ref(this);} \
- }; \
- \
- inline void ClassName ## Ref::operator=(const StructType& X) \
- {F->Write(X);} \
- inline void ClassName ## Ref::operator StructType() \
- {StructType X; F->Read(X); return X;}
-
-
- // friend void operator=(StructType& X,ClassName ## Ref R); \
- //inline void operator=(StructType& X,ClassName ## Ref R) \
- // {(R.F)->Read(X);}
-
- #ifdef __BORLANDC__
- #define FTMRO "rt"
- #define FTMRW "r+t"
- #else
- #define FTMRO "r"
- #define FTMRW "r+"
- #endif
-
- class TextFile:public LowLevelFile
- {
- Bool Started; // used to figure out whether we're starting off appending or reading
- public:
- TextFile(const char* FileName,Bool Mode=ReadAndWrite,int BufSize=BUFSIZ):
- LowLevelFile(FileName,((Mode==ReadOnly)?(FTMRO):(FTMRW)),BufSize)
- {Started=False;}
- void Seek(long Offset) {Started=True; LowLevelFile::Seek(Offset);}
- Bool Read(char* S);
- void Write(const char* S);
- void WriteLine(const char* S="");
- };
-
- void FileCopying(File& DestFile, File& SourceFile, long Size);
- // will not modify file positions before writing
-
- void CopyFile(const char* DestFile, const char* SourceFile);
- // source file must be created. if dest file already exists,
- // it will be deleted
-
- Word CRC(File& F,long FSize); // CRC of file starting at current pos
- Word CRC(File& F); // CRC of entire file
-
-
- /*
-
- Example of a file of records:
-
- struct XType
- {
- long a,b,c;
- };
-
- CreateRecFileClass(XFile,XType);
-
- main()
- {
- XType X;
- XFile F("X.BIN");
- F[0]=X;
- X=F[0];
- }
-
- */
-
- /*
- Features to add:
- 1) Make it so that a person cannot write beyond the end of their block
-
- */
-
- class TokenFile: public File
- {
- long MaxTokens;
- long FirstFreeBlock;
- long NextFreeToken;
- void GetFreeInfo(long Pos, long& Size, long& NextBlock);
- // used to traverse free list
- long FindSpace(long FSize);
- // returns a block number that can hold "FSize" and updates the
- // free list if needed
- void Delete(long Pos, long Size);
- // adds this info to the free list if its big enough
- void SeekIndexSlot(long Token) {File::Seek(Token*8);}
- void ReadCurIndexSlot(long& Pos, long& Size);
- friend Bool TokenExists(const char*,long);
- friend void ShowFreeList(const char*);
- public:
- TokenFile(const char* FileName, int BufSize=BUFSIZ);
- long Seek(long Token);
- /* returns the size of your object (0 if it doesn't exist). If
- object is found, file pointer is moved to your objects storage
- location. You may then read your data with any binary file type
- read. There will be nothing to stop you from reading too much */
- void WritePrep(long Token,long DataSize);
- /* sets up Token with a data area of just the right size. Any
- previous data under that Token is deleted. File pointer is left
- where writing may begin */
- void Delete(long Token);
- // makes the space that was taken by Token's object available
- long MaxToken(){return MaxTokens;}
- Bool TokenExists(long Token);
- void Extract(long Token,char* FileName);
- long NewToken();
- // will provide an unused token number
- long NewToken(long DataSize);
- // will allocate the space and provide an unused token number
- };
-
- Bool TokenExists(const char* FileName, long Token);
-
- void SaveBootRec(TokenFile& F,const char* CName);
- // Optional... Saves the video device boot info
-
- /* This class inherits all of the properties of the (binary) File class.
- It adds the feature of being able to store many little files into one
- larger file. Given a token ("access code", "key") value you may store and
- retrieve your data pretty much like any other binary file.
-
- Example of writing a struct of type XType:
-
- XType X;
- TokenFile F("DATA.BIN");
- F.WritePrep(326,sizeof(X)); // you pick your own Token number and object size
- F.WriteThing(X);
-
- Example of reading the same struct:
-
- XType X;
- TokenFile F("DATA.BIN");
- if (F.Seek(326)) F.ReadThing(X);
- else FatalError("cannot find my X thing in file DATA.BIN");
-
- */
-
- // all this stuff is sent out to the good ole stdprn
- void Print(const char* Text="");
- void Print(char C);
- void PrintLine(const char* X);
- void PrintFile(const char* FileName,int HeaderLines=0,Bool PageNumbers=False,
- VoidFuncPtr GrindFunc=NULL);
- inline void PrintFormFeed(){PrintLine("\f");}
-
- #endif
-